package com.cabal.common.util;

import org.apache.commons.lang.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 时间格式化工具类
 *
 * @author shenkang
 * @date 2023年3月7日
 * @version 1.0
 */
public class TmsDateUtil {


    public static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    public static final String MINUTE_PATTERN = "yyyy-MM-dd HH:mm";
    public static final String DATE_PATTERN = "yyyy-MM-dd";
    public static final String DATE_TIME_FORMAT_YYYYMMDD= "yyyyMMdd";
    public static final String DATE_TIME_FORMAT_YYYYMMDDHHMISS = "yyyyMMddHHmmss";
    public static final String DATE_TIME_FORMAT_YYYYMMDDHHMI = "yyyyMMddHHmm";
    public static final String DATE_TIME_FORMAT_YYYYMMDDHHMISSMI = "yyyyMMddHHmmssSSS";
    public static final String DATE_TIME_FORMAT_YYYY= "yyyy";
    public static final String DATE_TIME_FORMAT_MIHHDDMMYYYY= "dd/MM/yyyy HH:mm";
    public static final String DATE_TIME_FORMAT_MMDD= "MMdd";
    public static final String DATE_PATTERN_POINT = "yyyy.MM.dd";
    public static final String DATE_PATTERN_SLASH = "yyyy/MM/dd";

    public static String dateStrTrance(String str){
        if(StringUtils.isBlank(str) || str.length() == 8){
            return str;
        }
        SimpleDateFormat simpleDateFormat = null;
        if(str.contains("-") && str.length() == 10){
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        }
        if(str.length() == 19){
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
        if(str.length() == 16){
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        }
        try {
            return new SimpleDateFormat("yyyyMMdd").format(simpleDateFormat.parse(str));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 格式化Date时间
     * @param time Date类型时间
     * @param timeFromat String类型格式
     * @return 格式化后的字符串
     */
    public static String parseDateToStr(Date time, String timeFromat){
        SimpleDateFormat dateFormat=new SimpleDateFormat(timeFromat);
        if(time == null){
            return null;
        }
        return dateFormat.format(time);
    }


    /**
     * 格式化String时间
     * @param time String类型时间
     * @param timeFromat String类型格式
     * @return 格式化后的Date日期
     */
    public static Date parseStrToDate(String time, String timeFromat) {
        if (time == null || time.equals("")) {
            return null;
        }

        Date date = null;
        try {
            DateFormat dateFormat = new SimpleDateFormat(timeFromat);
            date = dateFormat.parse(time);
        } catch (Exception e) {

        }
        return date;
    }


    /**
     * 格式化String时间
     * @param strTime String类型时间
     * @param timeFromat String类型格式
     * @param defaultValue 异常时返回的默认值
     * @return
     */
    public static Date parseStrToDate(String strTime, String timeFromat,Date defaultValue) {
        try {
            DateFormat dateFormat = new SimpleDateFormat(timeFromat);
            return dateFormat.parse(strTime);
        } catch (Exception e) {
            return defaultValue;
        }

    }

    /**
     * 获取当前时间的后几天
     * @param dayNum
     * @param date
     * @return
     */
    public static String addDate(Date date,int dayNum) {
        try {
            SimpleDateFormat sdf=new SimpleDateFormat(DATE_PATTERN);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_MONTH, dayNum);
            date = calendar.getTime();
            return sdf.format(date);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取当前时间的前几天
     * @param dayNum
     * @param date
     * @return
     */
    public static String getBeforDate(int dayNum,Date date) {
        try {
            SimpleDateFormat sdf=new SimpleDateFormat(DATE_PATTERN);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_MONTH, -dayNum);
            date = calendar.getTime();
            return sdf.format(date);
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 获取指定时间的前几天
     * @param dayNum
     * @param date
     * @return
     */
    public static Date getBeforeDate(int dayNum,Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -dayNum);
        return calendar.getTime();
    }

    /**
     * 获取两个时间间隔天数
     *
     * @param startDateStr
     * @param endDateStr
     * @return
     */
    public static int differentDays(String startDateStr, String endDateStr){
        try {
            SimpleDateFormat format = new SimpleDateFormat(DATE_PATTERN);
            Date endTime = format.parse(endDateStr);
            Date startTime = format.parse(startDateStr);
            int days = (int) ((endTime.getTime() - startTime.getTime()) / (1000 * 3600 * 24));
            return days;
        } catch (Exception e) {
            return 0;
        }
    }

    public static Date addMonth(Date date, int i) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH,i);
        return cal.getTime();
    }


    public static String addBeforeMonth(Date date, int i) {
        SimpleDateFormat sdf=new SimpleDateFormat(DATE_PATTERN);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH,-i);
        date = cal.getTime();
        return sdf.format(date);
    }

    /**
     * Date2LocalDateTime
     * @param date
     * @return
     */
  public static LocalDateTime Date2LocalDateTime(Date date) {
      if(date == null){
          return null;
      }
      Instant instant = date.toInstant();
      ZoneId zoneId = ZoneId.systemDefault();
      LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
        return localDateTime;
    }

    public static LocalDate dateToLocalDate(Date date) {
        if(date == null){
            return null;
        }
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate();
        return localDate;
    }

    public static String parseLocalDateToStr(LocalDateTime localDateTimeOfNow, String timeFromat){

        DateTimeFormatter format = DateTimeFormatter.ofPattern(timeFromat);
        //格式化字符串
        String nowStr = localDateTimeOfNow.format(format);
        return nowStr;
    }

    public static String localDate2Str(LocalDate localDate, String format) {
        if (null == localDate) {
            return null;
        }
        ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
        Date date = Date.from(zonedDateTime.toInstant());
        return parseDateToStr(date, format);
    }

    public static LocalDate str2LocalDate(String strDate, String format) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
        return LocalDate.parse(strDate, formatter);
    }

    public static Date asDate(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay().atZone(getZoneId()).toInstant());
    }

    public static Date asDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(getZoneId()).toInstant());
    }

    public static LocalDate asLocalDate(Date date) {
        return Instant.ofEpochMilli(date.getTime()).atZone(getZoneId()).toLocalDate();
    }

    public static LocalDateTime asLocalDateTime(Date date) {
        return Instant.ofEpochMilli(date.getTime()).atZone(getZoneId()).toLocalDateTime();
    }

    public static ZoneId getZoneId(){
        return ZoneId.of("Asia/Shanghai");
    }

    public static List<Date> getWeeksBetweenDate(Date startTime, Date endTime) {
        List<Date> days = new ArrayList<>();
        int x = 0;
        while (true) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startTime);
            calendar.add(Calendar.DAY_OF_MONTH, x++);
            days.add(calendar.getTime());
            if (calendar.getTime().getTime() >= endTime.getTime()) {
                break;
            }
        }
        return days;
    }

//    public static void main(String[] args) {
//        Date startTime = parseStrToDate("2022-05-11 00:00:00", DATE_TIME_PATTERN);
//        Date endTime = parseStrToDate("2022-05-18 00:00:00", DATE_TIME_PATTERN);
//
//        List<Date> days = getWeeksBetweenDate(startTime, endTime);
//        for(Date date : days){
//            System.out.println(parseDateToStr(date,DATE_TIME_PATTERN));
//        }
//    }

}
